package com.knightsoft.desktopapp.jchatsystem;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.net.BindException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class ChatServerCore {
	
	//add connected client to container
	private List<Client> clients = new ArrayList<Client>();
	private boolean connectflag = false;
	private ServerSocket server = null;

	public static void main(String[] args) {

		new ChatServerCore().start();
	}

	public void start() {
		try {
			server = new ServerSocket(2000);
			System.out.println("Running at " + server.getInetAddress()+" :" + server.getLocalPort() );
		} catch (BindException e) {
			System.out.println("Server: Port is using by another application!");
			System.exit(0);
		} catch (IOException e) {
			e.printStackTrace();
		}

		try {
			connectflag = true;
			while (connectflag) {
				Socket socket = server.accept();
				Client c = new Client(socket);
				System.out.println("Client" + socket.getInetAddress()+":" + socket.getPort() + "Connected ..." );
				// 开启独立线程处理单个客户端连接
				new Thread(c).start();
				clients.add(c);
				// dis.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				server.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	class Client implements Runnable {

		private Socket socket;
		private Client c;
		private DataInputStream dis = null;
		private DataOutputStream dos = null;
		private boolean bconnected = false;

		public Client(Socket s) {
			socket = s;
			try {
				dis = new DataInputStream(socket.getInputStream());
				dos = new DataOutputStream(socket.getOutputStream());
				bconnected = true;
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		public void send(String msg) {
			try {
				dos.writeUTF(msg);
			} catch (IOException e) {
				clients.remove(this);
				System.out.println("Client Quit ...");
			}
		}
		
		//Version : 2.0
		public String getInetAddress () {
			return socket.getInetAddress().toString();
		}
		
		public String getPort2String() {
			return String.valueOf( socket.getPort());
		}
		
		public String getLocalSocketAddress () {
			return socket.getLocalAddress().toString();
		}
		
		@Override
		public void run() {
			try {
				while (bconnected) {
					String buffer;
					String msgHead;
					String tempMsg;
					
					buffer = dis.readUTF();
System.out.println(buffer);
					/*
					for (int i = 0; i < clients.size(); i++) {
						Client c = clients.get(i);
						c.send(buffer);
					}
					*/
					
					//使用迭代器
					//迭代时会进行锁定, 效率不高
					Iterator<Client> it = clients.iterator();
					while ( it.hasNext() ) {
						c = it.next();
						msgHead = c.getInetAddress() + ":" + c.getPort2String();
//System.out.println("Head"+msgHead);
//System.out.println("MSG" + buffer);
						if (buffer.contains(msgHead)) { 
							tempMsg = buffer.replace(msgHead, "me");
							c.send(tempMsg);
						}
						else
							c.send(buffer);
					}
				}
			} catch (EOFException e) {
System.out.println("Server: Client Closed ...");
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				try {
						if (dis != null) dis.close();
						if (dos != null) dos.close();
						if (socket != null) socket.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

}
